﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cofe.Core;
using Cofe.Core.EntryType;
using Cofe.Core.Property;
using Cofe.Core.Utils;
using Cofe.Core.Validater;
using Cofe.IO;
using Cofe.IO.Implements;
using Cofe.IO.Interfaces;
using Windows.Storage;
using Windows.Storage.FileProperties;
using Windows.UI.Xaml.Media.Imaging;

namespace Cofe.IO.Implements
{
#if NETFX_CORE
    //Guidelines for thumbnails - http://msdn.microsoft.com/en-us/library/windows/apps/hh465350.aspx
    public class WindowsStorageEntryTypeProvider : IEntryTypeIdentifier, IEntryTypeInfoProvider
    {
        public const string KeyPrefix = "WindowsStorage_";
        private class SystemProperties
        {
            public static string ItemTypeText = "System.ItemTypeText"; //File Type.
            public static string MIMEType = "System.MIMEType";
            public static string FileDescription = "System.FileDescription"; //A user-friendly description of the file.
            public static string Thumbnail = "System.Thumbnail";
        }

        #region Constructor

        #endregion

        #region Methods

        public string GetEntryTypeKey(IPropertyHost propertyHost)
        {
            if (propertyHost.PrimaryPropertyProvider is WindowsStoragePropertyProvider)
            {
                var entity = (propertyHost.PrimaryPropertyProvider as WindowsStoragePropertyProvider).Entity;
                string type = propertyHost.Behaviors.GetProperty(CofeProperties.Type).ValueAsString;
                string key;
                if (type.ToLower() == "file")
                {
                    string name = propertyHost.Behaviors.GetProperty(CofeProperties.Name).ValueAsString;
                    key = KeyPrefix + PathFE.GetExtension(name.ToLower());
                }
                key = KeyPrefix + type.ToLower();

                lock (_keyStorageItemDic)
                    if (!_keyStorageItemDic.ContainsKey(key))
                        _keyStorageItemDic.Add(key, entity);

                return key;
            }
            else return null;
        }

        private List<string> lookupList = new List<string>() { 
             SystemProperties.FileDescription, SystemProperties.ItemTypeText, SystemProperties.MIMEType, SystemProperties.Thumbnail
        };


        public async Task<PropertyPair[]> GetEntryTypeInfoAsync(string entryTypeKey)
        {
            if (entryTypeKey.StartsWith(KeyPrefix) && _keyStorageItemDic.ContainsKey(entryTypeKey))
            {
                List<PropertyPair> retVal = new List<PropertyPair>();

                string type = entryTypeKey.Replace(KeyPrefix, "");
                //string fileType, mimetype;
                IDictionary<string, object> propDic;
                if (type == "directory")
                {
                    StorageFolder storageFolder = _keyStorageItemDic[entryTypeKey] as StorageFolder;
                    propDic = await storageFolder.Properties.RetrievePropertiesAsync(lookupList);

                    //Action<object> addFolderIcon = (prop) =>
                    //    {
                    //        retVal.Add(new PropertyPair(prop, () => getIconStream(storageFolder, prop), false));
                    //    };


                    //foreach (var p in Cofe.Core.PropertyDefinitions.CofeIconDefinitions.GetSupportedProperties())
                    //    addFolderIcon(p);
                }
                else
                {
                    StorageFile storageFile = _keyStorageItemDic[entryTypeKey] as StorageFile;
                    propDic = await storageFile.Properties.RetrievePropertiesAsync(lookupList);

                    Action<object> addFileIcon = (prop) =>
                    {
                        retVal.Add(PropertyPair.FromValueFunc(prop, () => getIconStream(storageFile, prop), false));
                    };

                    foreach (var p in Cofe.Core.PropertyDefinitions.CofeIconDefinitions.GetSupportedProperties())
                        addFileIcon(p);
                }

                Action<string, object> addProperty = (key, toProp) =>
                    {
                        if (propDic.ContainsKey(key))
                            retVal.Add(PropertyPair.FromValue(toProp, propDic[key]));
                    };

                addProperty(SystemProperties.FileDescription, FileTypeInfoProperties.Description);
                addProperty(SystemProperties.MIMEType, FileTypeInfoProperties.MIMEType);
                addProperty(SystemProperties.ItemTypeText, FileTypeInfoProperties.FileType);
                //addProperty(SystemProperties.Thumbnail, CofeIconProperties.Thumbnail);     

                return retVal.ToArray();
            }

            return null;
        }

        //private BitmapSource getIconStream(object item, object property)
        //{
        //    Task<BitmapSource> _task;

        //    if (item is StorageFile)
        //        _task = getIconStreamAsync(item as StorageFile, property);
        //    else _task = getIconStreamAsync(item as StorageFolder, property);

        //    if (_task.Status == TaskStatus.Created)
        //        _task.Start();            
        //    return _task.Result;
        //}

        private BitmapContainer getIconStream(StorageFile file, object property)
        {
            try
            {
                int size = 32;
                bool isThumbnail = false;

                var attribute = AttributeUtils<BitmapSizeAttribute>.FindAttribute(property);
                if (attribute != null)
                {
                    size = attribute.Width;
                    isThumbnail = attribute.Height == -1;
                }

                var source = file.GetThumbnailAsync(
                    isThumbnail ? ThumbnailMode.PicturesView : ThumbnailMode.ListView,
                    (uint)size, ThumbnailOptions.ResizeThumbnail).AsTask().Result;


                return BitmapContainer.FromStorageItemThumbnail(source);
                
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        private BitmapContainer getIconStream(StorageFolder folder, object property)
        {
            int size = 32;
            bool isThumbnail = false;

            var attribute = AttributeUtils<BitmapSizeAttribute>.FindAttribute(property);
            if (attribute != null)
            {
                size = attribute.Width;
                isThumbnail = attribute.Height == -1;
            }

            var source = folder.GetThumbnailAsync(
                isThumbnail ? ThumbnailMode.PicturesView : ThumbnailMode.ListView,
                (uint)size, ThumbnailOptions.ResizeThumbnail).GetResults();

            return BitmapContainer.FromStorageItemThumbnail(source);
        }

        #endregion

        #region Data

        Dictionary<string, IStorageItem> _keyStorageItemDic = new Dictionary<string, IStorageItem>();

        #endregion

        #region Public Properties

        #endregion
    }
#endif
}
